#include <stdint.h>
#include <stdio.h>
#include <string.h>

//#include "driver_iomux.h"
#include "driver_gpio.h"
#include "driver_uart.h"

static UART_HandleTypeDef Uart3_handle;

void prog_uart_init(uint32_t bandrate)
{
    GPIO_InitTypeDef gpio_config;

    /* configure PB4 and PB5 to UART3 function */
    gpio_config.Pin = GPIO_PIN_4 | GPIO_PIN_5;
    gpio_config.Mode = GPIO_MODE_AF_PP;
    gpio_config.Pull = GPIO_PULLUP;
    gpio_config.Alternate = GPIO_FUNCTION_1;
    gpio_init(GPIOB, &gpio_config);

    /* UART3: used for Log and AT command */
    __SYSTEM_UART3_CLK_ENABLE();
    Uart3_handle.UARTx           = UART3;
    Uart3_handle.Init.BaudRate   = bandrate;
    Uart3_handle.Init.DataLength = UART_DATA_LENGTH_8BIT;
    Uart3_handle.Init.StopBits   = UART_STOPBITS_1;
    Uart3_handle.Init.Parity     = UART_PARITY_NONE;
    Uart3_handle.Init.FIFO_Mode  = UART_FIFO_ENABLE;
    Uart3_handle.TxCpltCallback  = NULL;
    Uart3_handle.RxCpltCallback  = NULL;
    uart_init(&Uart3_handle);
    NVIC_SetPriority(UART3_IRQn, 4);
    // NVIC_EnableIRQ(UART3_IRQn);

    // uart_receive_IT(&Uart3_handle, &app_at_recv_char, 1);
    system_delay_us(500);
}
void prog_uart_read(uint8_t *data, uint16_t length)
{
    uart_receive(&Uart3_handle, data, length);
}

uint16_t prog_uart_read_no_block(uint8_t *data, uint16_t length)
{
    int len = 0;
    UART_HandleTypeDef *huart = &Uart3_handle;

    while (len < length)
    {
        /* Rx ready */
        if (!(huart->UARTx->LSR.LSR_BIT.DR))
            break;
        /* receive data */
        data[len++] = huart->UARTx->DATA_DLL.DATA;
    }
    return len;
}

void prog_uart_write(uint8_t *data, uint16_t length)
{
    uart_transmit(&Uart3_handle, data, length);
}
